package com.nmf.timer;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.nmf.site.common.excep.KideException;
import com.nmf.site.common.excep.KideExpCode;


public class TimeConverter {
	private static final Logger log = LoggerFactory.getLogger(TimeConverter.class);

	/** yyyy-MM-dd HH:mm:ss */
	public static final String FULL_TIMESTAMP = "yyyy-MM-dd HH:mm:ss";
	public static final String INT_TIMESTAMP = "yyyyMMddHHmmss";
	/** yyyy-MM-dd */
	public static final String END_WITH_DATE = "yyyy-MM-dd";
	public static final String hour_data = "HH:mm:ss";
	public static final String hour_noms_data = "HH:mm";
	public static final String ISO_EXPANDED_DATE_FORMAT_POINT = "yyyy.MM.dd";
	public static String DATETIME_PATTERN_CHINESE = "yyyy年MM月dd日";

	public static Date converTime(String timestr, String... formattmp) throws ParseException {
		String pat1 = FULL_TIMESTAMP;
		if (formattmp != null && formattmp.length > 0) {
			pat1 = formattmp[0];
		}
		SimpleDateFormat sdf1 = new SimpleDateFormat(pat1);

		Date date = sdf1.parse(timestr);
		return date;
	}
	
	public static String getLastDayOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month - 1);
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DATE));
		return new SimpleDateFormat("yyyy-MM-dd ").format(cal.getTime());
	}

	public static Date getFirstDayOfMonth(int year, int month) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, month - 1);
		cal.set(Calendar.DAY_OF_MONTH, cal.getMinimum(Calendar.DATE));
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		return cal.getTime();
	}


	/**
	 * 
	 * @param dateTime
	 * @param pattern
	 *            格式，如yyyy-MM-dd HH:mm:ss， yyyy-MM-dd等
	 * @param fieldName
	 *            字段名。发生异常时，报告该字段值异常
	 * @return
	 */
	public static Date converTime(String dateTime, String pattern, String fieldName) {
		try {
			return TimeConverter.converTime(dateTime);
		} catch (ParseException e) {
			log.error(fieldName, e);
			throw new KideException(KideExpCode.BIZ_EQP_ERROR, e.toString());
		}
	}

	public static int getDaySub(String endDateStr, String beginDateStr) {
		Long day = 0l;
		java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
		java.util.Date beginDate;
		java.util.Date endDate;
		try {
			beginDate = format.parse(beginDateStr);
			endDate = format.parse(endDateStr);
			day = (endDate.getTime() - beginDate.getTime()) / (24 * 60 * 60 * 1000);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return day.intValue();
	}

	/**
	 * 格式：yyyy-MM-dd HH:mm:ss
	 * 
	 * @param dateTime
	 * @param fieldName
	 *            字段名。发生异常时，报告该字段值异常
	 * @return
	 */
	public static Date converTime(String dateTime, String fieldName) {
		return converTime(dateTime, FULL_TIMESTAMP, fieldName);
	}

	/**
	 * 把时间格式字符串转换为Date类型，当异常时抛出unchecked exception.
	 * 
	 * @param dateString
	 * @param format
	 * @return
	 */
	public static Date toDate(String dateString, String format) {
		if (StringUtils.isBlank(dateString))
			return null;
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		try {
			return dateFormat.parse(dateString);
		} catch (ParseException e) {
			log.error(e.getMessage());
			throw new KideException(KideExpCode.BIZ_EQP_ERROR, e.toString());
		}
	}

	/**
	 * 把时间格式字符串转换为Date类型，当异常时抛出unchecked exception.
	 * 
	 * @param dateString
	 * @return The pattern is yyyy-MM-dd HH:mm:ss
	 */
	public static Date toDate(String dateString) {
		return toDate(dateString, FULL_TIMESTAMP);
	}

	public static Timestamp convertTimestamp(String dateString) {
		if (StringUtils.isBlank(dateString))
			return null;
		SimpleDateFormat dateFormat = new SimpleDateFormat(FULL_TIMESTAMP);
		try {
			Date date = dateFormat.parse(dateString);
			return new Timestamp(date.getTime());
		} catch (ParseException e) {
			log.error(e.getMessage());
			throw new KideException(KideExpCode.BIZ_EQP_ERROR, e.toString());
		}

	}

	public static final Date getAddDate(Date beginDate, int nextDate) {
		SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
		Calendar date = Calendar.getInstance();
		date.setTime(beginDate);
		date.set(Calendar.DATE, date.get(Calendar.DATE) + nextDate);
		Date endDate = null;
		try {
			endDate = dft.parse(dft.format(date.getTime()));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			throw new KideException(KideExpCode.BIZ_EQP_ERROR, e.toString());
		}

		return endDate;
	}
	
	public static final Date getAddDateSeconds(Date beginDate, int nextDate) {
		SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar date = Calendar.getInstance();
		date.setTime(beginDate);
		date.set(Calendar.DATE, date.get(Calendar.DATE) + nextDate);
		Date endDate = null;
		try {
			endDate = dft.parse(dft.format(date.getTime()));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			throw new KideException(KideExpCode.BIZ_EQP_ERROR, e.toString());
		}

		return endDate;
	}
	
	public static final String getAddDateStr(Date beginDate, int nextDate) {
		SimpleDateFormat dft = new SimpleDateFormat("yyyy-MM-dd");
		Calendar date = Calendar.getInstance();
		date.setTime(beginDate);
		date.set(Calendar.DATE, date.get(Calendar.DATE) + nextDate);
		return dft.format(date.getTime());
	}

	public static Timestamp convertTimestampD(String dateString) {
		if (StringUtils.isBlank(dateString))
			return null;
		SimpleDateFormat dateFormat = new SimpleDateFormat(END_WITH_DATE);
		try {
			Date date = dateFormat.parse(dateString);
			return new Timestamp(date.getTime());
		} catch (ParseException e) {
			log.error(e.getMessage());
			throw new KideException(KideExpCode.BIZ_EQP_ERROR, e.toString());
		}

	}

	/**
	 * 
	 * @param date
	 * @param pattern
	 *            yyyy-MM-dd HH:mm:ss, if null
	 * @return null, if ${date} is null
	 */
	public static final String formatDate(Date date, String pattern) {
		if (date == null)
			return null;
		if (pattern == null)
			pattern = FULL_TIMESTAMP;
		return new SimpleDateFormat(pattern).format(date);
	}
	
	public static final String formatCouponDate(Date date) {
		return new SimpleDateFormat(TimeConverter.ISO_EXPANDED_DATE_FORMAT_POINT).format(date);
	}

	/**
	 * 
	 * @param date
	 * @return null, if ${date} is null
	 */
	public static final String formatDateToInt(Date date) {
		if (date == null)
			return null;
		return new SimpleDateFormat(INT_TIMESTAMP).format(date);
	}

	/**
	 * @param date
	 * @return format: yyyy-MM-dd HH:mm:ss
	 */
	public static final String formatDate(Date date) {
		return formatDate(date, FULL_TIMESTAMP);
	}

	/**
	 * @param date
	 * @return format: yyyy-MM-dd
	 */
	public static final String formatDates(Date date) {
		return formatDate(date, END_WITH_DATE);
	}
	/**
	 * 获取当前日期时间最大值，精确到ms<br>
	 * 例如：yyyy-mm-dd 23:59:59.999
	 * @param date
	 * @return
	 */
	public static Date getDayMax(Date date){
		date = DateUtils.setHours(date, 23);
		date = DateUtils.setMinutes(date, 59);
		date = DateUtils.setSeconds(date, 59);
		date = DateUtils.setMilliseconds(date, 999);
		return date;
	}

	public static Date getForwardYear(Date date, int year) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR, 1);
		date = calendar.getTime();
		return date;
	}

	/**
	 * 获取 T-N月
	 * @param date
	 * @param month
	 * @return
	 */
	public static Date getBackMont(Date date, int month){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, -month);
		date = calendar.getTime();
		return date;
	}
	
	public static String getDateByWeek(Date date) {
		String dayInfo = formatDate(date, END_WITH_DATE);
		String hourInfo = formatDate(date, hour_noms_data);
		String weekInfo = getWeek(date);
		return dayInfo + " " + weekInfo + " " + hourInfo;
	}

	public static String getDateByWeekNoHour(Date date) {
		String dayInfo = formatDate(date, END_WITH_DATE);
		String weekInfo = getWeek(date);
		return dayInfo + " " + weekInfo;
	}

	public static String getWeek(Date date) {
		String[] weeks = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (week_index < 0) {
			week_index = 0;
		}
		return weeks[week_index];
	}
	
	public static String getSolrTimeFormat(Date date){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
		return sdf.format(date);
	}

	public static Date nextMonthFirstDate() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.add(Calendar.MONTH, 1);
		return calendar.getTime();
	}
}
